home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 32 / advsys.zip / ADVDBS.C < prev    next >
Text File  |  1987-06-28  |  12KB  |  536 lines

  1. /* advdbs.c - adventure database access routines */
  2. /*
  3.     Copyright (c) 1986, by David Michael Betz
  4.     All rights reserved
  5. */
  6.  
  7. #include <setjmp.h>
  8. #include "advint.h"
  9. #include "advdbs.h"
  10.  
  11. /* global variables */
  12. int h_init;    /* initialization code */
  13. int h_update;    /* update code */
  14. int h_before;    /* before handler code */
  15. int h_after;    /* after handler code */
  16. int h_error;    /* error handling code */
  17. int datafd;    /* data file descriptor */
  18.  
  19. /* external variables */
  20. extern jmp_buf restart;
  21.  
  22. /* external routines */
  23. extern char *malloc();
  24.  
  25. /* table base addresses */
  26. char *wtable;    /* word table */
  27. char *wtypes;    /* word type table */
  28. int wcount;    /* number of words */
  29. char *otable;    /* object table */
  30. int ocount;    /* number of objects */
  31. char *atable;    /* action table */
  32. int acount;    /* number of actions */
  33. char *vtable;    /* variable table */
  34. int vcount;    /* number of variables */
  35. char *data;    /* base of data tables */
  36. char *base;    /* current base address */
  37. char *dbase;    /* base of the data space */
  38. char *cbase;    /* base of the code space */
  39. int length;    /* length of resident data structures */
  40.  
  41. /* data file header */
  42. static char hdr[HDR_SIZE];
  43.  
  44. /* save parameters */
  45. static long saveoff;    /* save data file offset */
  46. static char *save;    /* save area base address */
  47. static int slen;    /* save area length */
  48.  
  49. /* db_init - read and decode the data file header */
  50. db_init(name)
  51.   char *name;
  52. {
  53.     int woff,ooff,aoff,voff,n;
  54.  
  55.     /* open the data file */
  56.     if (!advopen(name,&datafd))
  57.     advfatal("can't open data file");
  58.  
  59.     /* read the header */
  60.     if (!advread(datafd,hdr,HDR_SIZE))
  61.     advfatal("bad data file");
  62.     complement(hdr,HDR_SIZE);
  63.     base = hdr;
  64.  
  65.     /* check the magic information */
  66.     if (strncmp(&hdr[HDR_MAGIC],"ADVSYS",6) != 0)
  67.     advfatal("not an adventure data file");
  68.  
  69.     /* check the version number */
  70.     if ((n = getword(HDR_VERSION)) < 101 || n > VERSION)
  71.     advfatal("interpreter doesn't match data file");
  72.  
  73.     /* decode the resident data length header field */
  74.     length = getword(HDR_LENGTH);
  75.  
  76.     /* allocate space for the resident data structure */
  77.     if ((data = malloc(length)) == 0)
  78.     advfatal("insufficient memory");
  79.  
  80.     /* compute the offset to the data */
  81.     saveoff = (long)getword(HDR_DATBLK) * 512L;    
  82.  
  83.     /* read the resident data structure */
  84.     if (!advseek(datafd,saveoff))
  85.     advfatal("can't position data file");
  86.     if (!advread(datafd,data,length))
  87.     advfatal("bad data file");
  88.     complement(data,length);
  89.  
  90.     /* get the table base addresses */
  91.     wtable = data + (woff = getword(HDR_WTABLE));
  92.     wtypes = data + getword(HDR_WTYPES) - 1;
  93.     otable = data + (ooff = getword(HDR_OTABLE));
  94.     atable = data + (aoff = getword(HDR_ATABLE));
  95.     vtable = data + (voff = getword(HDR_VTABLE));
  96.  
  97.     /* get the save data area */
  98.     saveoff += (long)getword(HDR_SAVE);
  99.     save = data + getword(HDR_SAVE);
  100.     slen = getword(HDR_SLEN);
  101.  
  102.     /* get the base of the data and code spaces */
  103.     dbase = data + getword(HDR_DBASE);
  104.     cbase = data + getword(HDR_CBASE);
  105.  
  106.     /* initialize the message routines */
  107.     msg_init(datafd,getword(HDR_MSGBLK));
  108.  
  109.     /* get the code pointers */
  110.     h_init = getword(HDR_INIT);
  111.     h_update = getword(HDR_UPDATE);
  112.     h_before = getword(HDR_BEFORE);
  113.     h_after = getword(HDR_AFTER);
  114.     h_error = getword(HDR_ERROR);
  115.  
  116.     /* get the table lengths */
  117.     base = data;
  118.     wcount = getword(woff); 
  119.     ocount = getword(ooff);
  120.     acount = getword(aoff);
  121.     vcount = getword(voff);
  122.  
  123.     /* setup the base of the resident data */
  124.     base = dbase;
  125.  
  126.     /* set the object count */
  127.     setvalue(V_OCOUNT,ocount);
  128. }
  129.  
  130. /* db_save - save the current database */
  131. db_save()
  132. {
  133.     char name[50];
  134.     int fd;
  135.  
  136.     /* get the save file name */
  137.     if (!advsfile(name))
  138.     return (0);
  139.  
  140.     /* create the data file */
  141.     if (!advcreate(name,&fd))
  142.     return (0);
  143.  
  144.     /* write the header */
  145.     if (!advwrite(fd,&hdr[HDR_ANAME],20)) {
  146.     advclose(fd);
  147.     return (0);
  148.     }
  149.  
  150.     /* write the data */
  151.     if (!advwrite(fd,save,slen)) {
  152.     advclose(fd);
  153.     return (0);
  154.     }
  155.  
  156.     /* close the file */
  157.     if (!advclose(fd))
  158.     return (0);
  159.  
  160.     /* return successfully */
  161.     return (1);
  162. }
  163.  
  164. /* db_restore - restore a saved database */
  165. int db_restore()
  166. {
  167.     char name[50],hbuf[20],*p1,*p2;
  168.     int fd,i;
  169.  
  170.     /* get the save file name */
  171.     if (!advrfile(name))
  172.     return (0);
  173.  
  174.     /* open the data file */
  175.     if (!advopen(name,&fd))
  176.     return (0);
  177.  
  178.     /* read the header */
  179.     if (!advread(fd,hbuf,20)) {
  180.     advclose(fd);
  181.     return (0);
  182.     }
  183.  
  184.     /* compare the headers */
  185.     for (p1 = &hdr[HDR_ANAME], p2 = hbuf, i = 20; --i >= 0; )
  186.     if (*p1++ != *p2++) {
  187.         trm_str("This save file does not match the adventure!\n");
  188.         advclose(fd);
  189.         return (0);
  190.     }
  191.  
  192.     /* read the data */
  193.     if (!advread(fd,save,slen)) {
  194.     advclose(fd);
  195.     return (0);
  196.     }
  197.  
  198.     /* close the file and return successfully */
  199.     if (!advclose(fd))
  200.     return (0);
  201.  
  202.     /* return successfully */
  203.     return (1);
  204. }
  205.  
  206. /* db_restart - restart the current game */
  207. db_restart()
  208. {
  209.     if (!advseek(datafd,saveoff))
  210.     return (NIL);
  211.     if (!advread(datafd,save,slen))
  212.     return (NIL);
  213.     complement(save,slen);
  214.     setvalue(V_OCOUNT,ocount);
  215.     longjmp(restart,1);
  216. }
  217.  
  218. /* complement - complement a block of memory */
  219. complement(adr,len)
  220.   char *adr; int len;
  221. {
  222.     for (; len--; adr++)
  223.     *adr = ~(*adr + 30);
  224. }
  225.  
  226. /* findword - find a word in the dictionary */
  227. int findword(word)
  228.   char *word;
  229. {
  230.     char sword[WRDSIZE+1];
  231.     int wrd,i;
  232.  
  233.     /* shorten the word */
  234.     strncpy(sword,word,WRDSIZE); sword[WRDSIZE] = 0;
  235.  
  236.     /* look up the word */
  237.     for (i = 1; i <= wcount; i++) {
  238.     wrd = getwloc(i);
  239.     if (strcmp(base+wrd+2,sword) == 0)
  240.         return (getword(wrd));
  241.     }
  242.     return (NIL);
  243. }
  244.  
  245. /* wtype - return the type of a word */
  246. int wtype(wrd)
  247.   int wrd;
  248. {
  249.     return (wtypes[wrd]);
  250. }
  251.  
  252. /* match - match an object against a name and list of adjectives */
  253. int match(obj,noun,adjs)
  254.   int obj,noun,*adjs;
  255. {
  256.     int *aptr;
  257.  
  258.     if (!hasnoun(obj,noun))
  259.     return (FALSE);
  260.     for (aptr = adjs; *aptr != NIL; aptr++)
  261.     if (!hasadjective(obj,*aptr))
  262.         return (FALSE);
  263.     return (TRUE);
  264. }
  265.  
  266. /* checkverb - check to see if this is a valid verb */
  267. int checkverb(verbs)
  268.   int *verbs;
  269. {
  270.     int act;
  271.  
  272.     /* look up the action */
  273.     for (act = 1; act <= acount; act++)
  274.     if (hasverb(act,verbs))
  275.         return (act);
  276.     return (NIL);
  277. }
  278.  
  279. /* findaction - find an action matching a description */
  280. findaction(verbs,preposition,flag)
  281.   int *verbs,preposition,flag;
  282. {
  283.     int act,mask;
  284.  
  285.     /* look up the action */
  286.     for (act = 1; act <= acount; act++) {
  287.     if (preposition && !haspreposition(act,preposition))
  288.         continue;
  289.     if (!hasverb(act,verbs))
  290.         continue;
  291.     mask = ~getabyte(act,A_MASK);
  292.     if ((flag & mask) == (getabyte(act,A_FLAG) & mask))
  293.         return (act);
  294.     }
  295.     return (NIL);
  296. }
  297.  
  298. /* getp - get the value of an object property */
  299. int getp(obj,prop)
  300.   int obj,prop;
  301. {
  302.     int p;
  303.  
  304.     for (; obj; obj = getofield(obj,O_CLASS))
  305.     if (p = findprop(obj,prop))
  306.         return (getofield(obj,p));
  307.     return (NIL);
  308. }
  309.  
  310. /* setp - set the value of an object property */
  311. int setp(obj,prop,val)
  312.   int obj,prop,val;
  313. {
  314.     int p;
  315.  
  316.     for (; obj; obj = getofield(obj,O_CLASS))
  317.     if (p = findprop(obj,prop))
  318.         return (putofield(obj,p,val));
  319.     return (NIL);
  320. }
  321.  
  322. /* findprop - find a property */
  323. int findprop(obj,prop)
  324.   int obj,prop;
  325. {
  326.     int n,i,p;
  327.  
  328.     n = getofield(obj,O_NPROPERTIES);
  329.     for (i = p = 0; i < n; i++, p += 4)
  330.     if ((getofield(obj,O_PROPERTIES+p) & 0x7FFF) == prop)
  331.         return (O_PROPERTIES+p+2);
  332.     return (NIL);
  333. }
  334.  
  335. /* hasnoun - check to see if an object has a specified noun */
  336. int hasnoun(obj,noun)
  337.   int obj,noun;
  338. {
  339.     while (obj) {
  340.     if (inlist(getofield(obj,O_NOUNS),noun))
  341.         return (TRUE);
  342.     obj = getofield(obj,O_CLASS);
  343.     }
  344.     return (FALSE);
  345. }
  346.  
  347. /* hasadjective - check to see if an object has a specified adjective */
  348. int hasadjective(obj,adjective)
  349.   int obj,adjective;
  350. {
  351.     while (obj) {
  352.     if (inlist(getofield(obj,O_ADJECTIVES),adjective))
  353.         return (TRUE);
  354.     obj = getofield(obj,O_CLASS);
  355.     }
  356.     return (FALSE);
  357. }
  358.  
  359. /* hasverb - check to see if this action has this verb */
  360. int hasverb(act,verbs)
  361.   int act,*verbs;
  362. {
  363.     int link,word,*verb;
  364.  
  365.     /* get the list of verbs */
  366.     link = getafield(act,A_VERBS);
  367.  
  368.     /* look for this verb */
  369.     while (link != NIL) {
  370.     verb = verbs;
  371.     word = getword(link+L_DATA);
  372.     while (*verb != NIL && word != NIL) {
  373.         if (*verb != getword(word+L_DATA))
  374.         break;
  375.         verb++;
  376.         word = getword(word+L_NEXT);
  377.     }
  378.     if (*verb == NIL && word == NIL)
  379.         return (TRUE);
  380.     link = getword(link+L_NEXT);
  381.     }
  382.     return (FALSE);
  383. }
  384.  
  385. /* haspreposition - check to see if an action has a specified preposition */
  386. int haspreposition(act,preposition)
  387.   int act,preposition;
  388. {
  389.     return (inlist(getafield(act,A_PREPOSITIONS),preposition));
  390. }
  391.  
  392. /* inlist - check to see if a word is an element of a list */
  393. int inlist(link,word)
  394.   int link,word;
  395. {
  396.     while (link != NIL) {
  397.     if (word == getword(link+L_DATA))
  398.         return (TRUE);
  399.     link = getword(link+L_NEXT);
  400.     }
  401.     return (FALSE);
  402. }
  403.  
  404. /* getofield - get a field from an object */
  405. int getofield(obj,off)
  406.   int obj,off;
  407. {
  408.     return (getword(getoloc(obj)+off));
  409. }
  410.  
  411. /* putofield - put a field into an object */
  412. int putofield(obj,off,val)
  413.   int obj,off,val;
  414. {
  415.     return (putword(getoloc(obj)+off,val));
  416. }
  417.  
  418. /* getafield - get a field from an action */
  419. int getafield(act,off)
  420.   int act,off;
  421. {
  422.     return (getword(getaloc(act)+off));
  423. }
  424.  
  425. /* getabyte - get a byte field from an action */
  426. int getabyte(act,off)
  427.   int act,off;
  428. {
  429.     return (getbyte(getaloc(act)+off));
  430. }
  431.  
  432. /* getoloc - get an object from the object table */
  433. int getoloc(n)
  434.   int n;
  435. {
  436.     if (n < 1 || n > ocount)
  437.     nerror("object number out of range: %d",n);
  438.     return (getdword(otable+n+n));
  439. }
  440.  
  441. /* getaloc - get an action from the action table */
  442. int getaloc(n)
  443.   int n;
  444. {
  445.     if (n < 1 || n > acount)
  446.     nerror("action number out of range: %d",n);
  447.     return (getdword(atable+n+n));
  448. }
  449.  
  450. /* getvalue - get the value of a variable from the variable table */
  451. int getvalue(n)
  452.   int n;
  453. {
  454.     if (n < 1 || n > vcount)
  455.     nerror("variable number out of range: %d",n);
  456.     return (getdword(vtable+n+n));
  457. }
  458.  
  459. /* setvalue - set the value of a variable in the variable table */
  460. int setvalue(n,v)
  461.   int n,v;
  462. {
  463.     if (n < 1 || n > vcount)
  464.     nerror("variable number out of range: %d",n);
  465.     return (putdword(vtable+n+n,v));
  466. }
  467.  
  468. /* getwloc - get a word from the word table */
  469. int getwloc(n)
  470.   int n;
  471. {
  472.     if (n < 1 || n > wcount)
  473.     nerror("word number out of range: %d",n);
  474.     return (getdword(wtable+n+n));
  475. }
  476.  
  477. /* getword - get a word from the data array */
  478. int getword(n)
  479.   int n;
  480. {
  481.     return (getdword(base+n));
  482. }
  483.  
  484. /* putword - put a word into the data array */
  485. int putword(n,w)
  486.   int n,w;
  487. {
  488.     return (putdword(base+n,w));
  489. }
  490.  
  491. /* getbyte - get a byte from the data array */
  492. int getbyte(n)
  493.   int n;
  494. {
  495.     return (*(base+n) & 0xFF);
  496. }
  497.  
  498. /* getcbyte - get a code byte */
  499. int getcbyte(n)
  500.   int n;
  501. {
  502.     return (*(cbase+n) & 0xFF);
  503. }
  504.  
  505. /* getcword - get a code word */
  506. int getcword(n)
  507.   int n;
  508. {
  509.     return (getdword(cbase+n));
  510. }
  511.  
  512. /* getdword - get a word from the data array */
  513. int getdword(p)
  514.   char *p;
  515. {
  516.     return ((*p & 0xFF) | (*(p+1) << 8));
  517. }
  518.  
  519. /* putdword - put a word into the data array */
  520. int putdword(p,w)
  521.   char *p; int w;
  522. {
  523.     *p = w; *(p+1) = w >> 8;
  524.     return (w);
  525. }
  526.  
  527. /* nerror - handle errors with numeric arguments */
  528. nerror(fmt,n)
  529.   char *fmt; int n;
  530. {
  531.     char buf[100];
  532.     sprintf(buf,fmt,n);
  533.     advfatal(buf);
  534. }
  535.  
  536.